//////////////////////////////////////////////////////////////////
// (c) Copyright 2010-  by Jeongnim Kim
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//   National Center for Supercomputing Applications &
//   Materials Computation Center
//   University of Illinois, Urbana-Champaign
//   Urbana, IL 61801
//   e-mail: jnkim@ncsa.uiuc.edu
//
// Supported by 
//   National Center for Supercomputing Applications, UIUC
//   Materials Computation Center, UIUC
//////////////////////////////////////////////////////////////////
// -*- C++ -*-
/**@file fft3d_engine_a2av.hpp
 */
#include <fft3d/pencildecomp.hpp>
#ifndef QMCPLUSPLUS_FFT3D_ENGINE_A2AV_HPP
#define QMCPLUSPLUS_FFT3D_ENGINE_A2AV_HPP
namespace mpi
{

  template<typename T>
    struct FFT3DEngineA2AV: public PencilDecomp<T>
  {
    typedef PencilDecomp<T> LayoutType;

    FFT3DEngineA2AV(int l, int nx, int ny, int ipx, int ipy)
      : LayoutType(l,nx,ny,ipx,ipy)
    { }

    FFT3DEngineA2AV(int l, int ny, communicator& c)
      : LayoutType(l,ny,c)
    {}

    void fft_forward(int nvar)
    {
      qmcplusplus::Timer clock;
      for(int ivar=0; ivar<nvar; ++ivar)
      {
        fft1d(0);

        clock.restart();
        alltoallv(*rowComm,&rowBuffer[0],&rowCounts[0],&rowOffsets[0],&colBuffer[0],&rowCounts[0],&rowOffsets[0]);
        wtime[ROWTRANS_T]+=clock.elapsed();

        fft1d(1);

        clock.restart();
        alltoallv(*colComm,&colBuffer[0],&colCounts[0],&colOffsets[0],&rowBuffer[0],&colCounts[0],&colOffsets[0]);
        wtime[COLTRANS_T]+=clock.elapsed();

        fft1d(2);
      }
    }

    void fft_backward(int nvar)
    {
      qmcplusplus::Timer clock;
      for(int ivar=0; ivar<nvar; ++ivar)
      {
        fft1d(2);

        clock.restart();
        alltoallv(*colComm,&colBuffer[0],&colCounts[0],&colOffsets[0],&rowBuffer[0],&colCounts[0],&colOffsets[0]);
        wtime[COLTRANS_T]+=clock.elapsed();

        fft1d(1);

        clock.restart();
        alltoallv(*rowComm,&rowBuffer[0],&rowCounts[0],&rowOffsets[0],&colBuffer[0],&rowCounts[0],&rowOffsets[0]);
        wtime[ROWTRANS_T]+=clock.elapsed();

        fft1d(0);
      }
    }
  };
}
#endif
/***************************************************************************
 * $RCSfile$   $Author: jnkim $
 * $Revision: 1770 $   $Date: 2007-02-17 17:45:38 -0600 (Sat, 17 Feb 2007) $
 * $Id: fft2d.cpp 1770 2007-02-17 23:45:38Z jnkim $ 
 ***************************************************************************/
